/*
 * RayTracer.h
 * Contains the scene objects, lights and rays
 * Contains the functions needed to recursively trace the scene
 *
 * @version 	1.00 Feb 2011
 * @author 		Eric Stock
 */

#ifndef __RayTracerH
#define __RayTracerH
#include <fstream>
#include <iostream>
#include "MathLib.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Utility.h"
#include "Tree.h"
#include "Photon.h"
#include "Light.h"
#include "Primitive.h"

class RayTracer
{
    
	/** create a private copy constructor and private assignment operators */
	/** to prevent bitwise/shallow copies which may result in dangling pointers */
		RayTracer(RayTracer& r);
		RayTracer& operator=(RayTracer& r);

	public:
        
		static int noSphereIntersections;
		
		struct ThreadArgs
		{
			RayTracer* tPtr;
			int		   scanLineId;
		};
		
		static const char* strSceneFile;
		static const flt smallValue;
		
		RayTracer();
		
		
		~RayTracer();

		static void RayTracer::LaunchThread(void* p_pParam);
		
		void RayTracer::NextFrame();				//repositions items to display the next frame
		void RayTracer::PhotonMapScene();
		void RayTracer::TestRandomHemisphereVector();
		void RayTracer::IntersectScene(int p_iScanLineId);     
		void RayTracer::UpdateCameraPos(int p_iFrame);
		void RayTracer::IntitializeScene();  
		void RayTracer::GenScreenDirections();
		int GetHeight() {
           return m_iScreenHeight;
        }
        int GetWidth() {
           return m_iScreenWidth;
        }
        Pics* GetImage() {
            return m_pImageData;
        }    
		
	private:	
		void RayTracer::TraceRay(int p_iCount, math::Vertex& p_vOrigin, math::Vector& p_vDirection, Colour& p_Colour, flt p_fColourAmount, flt p_fN1);
        void RayTracer::ReadComment(FILE * p_pFile);
		math::Vector RayTracer::GetRandomNormalInHemisphere(math::Vector& p_vNormal);

        Light**			m_pLights;
		Tree::Box**		m_pAreaLightBoxes;
		Sphere2*		m_pSpheres;
        Plane2*			m_pPlanes;
		Primitive**		m_arrPrimitives;
		Pics*			m_pImageData;
        Photon*			m_pPhotons;
		Samples*		m_pSamples;
		math::Vertex	m_vOrigin;				//eye position of scene
        Colour			m_ColourAmbient;			//global ambient light values
        Tree			m_treeBSP;			//binary space partition tree
		
        flt				m_fCameraCircleRadius;
        flt				m_fCameraCircleAngle;
        int				m_iScreenHeight;
        int				m_iScreenWidth;
        int				m_iNumberLights;
        int				m_iNumberSpheres;
		int				m_iNumberPlanes;
};    

#endif